#include "CGameClass.h"
#include <ctime>
//#include "CMainGameState.h"
#include "CGamePlayState.h"
#include "CSGD_DirectInput.h"
//#include "DXControl.h"
//#include "TextureManager.h"
#include "CSGD_FModManager.h"
#include "CMainMenuState.h"

void CGameClass::Init(HWND* _pHWND, HINSTANCE *_pHINSTANCE, int _width, int _height)
{
	m_bIsRunning = true;
	m_pHWND = _pHWND;
	m_pHINSTANCE = _pHINSTANCE;

	m_nScreenWidth = _width;
	m_nScreenHeight = _height;

	srand(unsigned int(time(0)));
	m_pTimer = CTimer::GetInstance();
	m_pMessenger = CMessenger::GetInstance();
	m_pMessenger->SetHandler(MsgProc);
	m_pDispatcher = CDispatcher::GetInstance();

	//InitDX();
	
	CSGD_FModManager::GetInstance()->InitFModManager( *_pHWND );

	// Init input
	m_pDI = CSGD_DirectInput::GetInstance();
	m_pDI->InitDirectInput( *m_pHWND, *m_pHINSTANCE, DI_KEYBOARD | DI_MOUSE | DI_JOYSTICKS, 0 );

	//OnLostDevice();
	//if(m_devControl->SetScreenSize( (unsigned int)m_nScreenWidth, (unsigned int)m_nScreenHeight ))
	//{
	//	OnResetDevice();
	//}

	//// init texturemanager
	//TextureManager::GetInstance()->Init( m_devControl->GetDevice() );

	ChangeState(CMainMenuState::GetInstance());
	/*ChangeState(CGamePlayState::GetInstance());*/
}
void CGameClass::Update(void) 
{
	CSGD_FModManager::GetInstance()->Update();
	m_StateStack.top()->Update( m_pTimer->GetElapsedTime() );
}

void CGameClass::Render(void) 
{
	m_StateStack.top()->Render();
	//if(!m_devControl->IsDeviceWorking())
	//{
	//	if(m_devControl->CheckDevice())
	//	{
	//		OnLostDevice();
	//		if(m_devControl->ResetDevice())
	//		{
	//			OnResetDevice();
	//		}
	//	}
	//}
	//else
	//{
	//	m_devControl->BeginRendering( true, true, true, 0, 0, 0 );
	//	{
	//		m_StateStack.top()->Render();
	//	}
	//	m_devControl->EndRendering();
	//}
	// game states
}

void CGameClass::Input(void) 
{
	m_pDI->ReadDevices();
	
	if( m_pDI->KeyPressed( DIK_ESCAPE ) )
	{
		m_bIsRunning = FALSE;
	}

	m_StateStack.top()->Input();
}

bool CGameClass::GameLoop()
{
	m_pTimer->Tick();

	Input();
	Update();
	Render();

	m_pDispatcher->ProcessEvents();
	m_pMessenger->ProcessMessages();

	return m_bIsRunning;
}

void CGameClass::Shutdown()
{
	ClearStateStack();

	CSGD_FModManager::GetInstance()->ShutdownFModManager();
	
	//TextureManager::GetInstance()->Shutdown();

	// direct input
	if(m_pDI) {
		m_pDI->ShutdownDirectInput();
		m_pDI = NULL;
	}
	// release device
	//m_devControl->ReleaseInstance();
}

void CGameClass::ClearStateStack()
{
	while (!m_StateStack.empty())
	{
		m_StateStack.top()->Exit();
		m_StateStack.pop();
	}
}

void CGameClass::ChangeState(CBaseGameState *pState)
{
	ClearStateStack();

	PushState(pState);
}

void CGameClass::PushState(CBaseGameState *pState)
{
	if (pState)
	{
		m_StateStack.push(pState);
		pState->Enter();
	}
}

void CGameClass::PopState()
{
	if (!m_StateStack.empty())
	{
		m_StateStack.top()->Exit();
		m_StateStack.pop();
	}
}

void MsgProc(string szID, void *pSender, void *pArgs)
{
	CGameClass *pGame = CGameClass::GetInstance();
	if (szID == "MouseDown")
	{
		POINT pt = *((POINT *)pArgs);
		delete pArgs;
	}
	else if (szID == "MouseMove")
	{
		POINT pt = *((POINT *)pArgs);
		delete pArgs;
	}
	else if (szID == "MouseUp")
	{
		POINT pt = *((POINT *)pArgs);
		delete pArgs;
	}
}